﻿using System;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using ENail.Domain.Core;
using ENail.Domain.Core.Contract.Services;
using ENail.Portal.Web.Models;
using Equation.Enterprise.Utilities.DesignByContract;
using System.Collections.Generic;
using Equation.Enterprise.Framework.Web.Model;
using Telerik.Web.Mvc;

namespace ENail.Portal.Web.Controllers
{
    public class EntryController : BaseController
    {
        private readonly ICustomerService _customerService;
        private readonly IEmployeeService _employeeService;
        private readonly INailServiceService _nailServiceService;
        private readonly IRegistrationService _registrationService;
        private readonly IAssignmentService _assignmentService;
        private readonly ITaskService _taskService;
        private TaskManager _taskManager;

        public EntryController(ICustomerService customerService, IEmployeeService employeeService, INailServiceService nailServiceService, IRegistrationService registrationService,ITaskService taskService,IAssignmentService assignmentService )
        {
            Check.Require(customerService != null);
            Check.Require(employeeService != null);
            Check.Require(nailServiceService != null);
            Check.Require(registrationService != null);
            Check.Require(assignmentService!=null);
            Check.Require(taskService != null);
            _customerService = customerService;
            _employeeService = employeeService;
            _nailServiceService = nailServiceService;
            _registrationService = registrationService;
            _assignmentService = assignmentService;
            _taskService = taskService;
            _taskManager = new TaskManager(_taskService);
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Index(int? id)
        {
            var registration = id.HasValue ? _registrationService.GetRegistration(id.Value) : new Registration();
            var entryViewModel = PrepareViewModel(registration);

            return View(entryViewModel);
        }

        /// <summary>
        /// This action will update/create customer base on customerId!=0 or customerId==0
        /// It then update/create a new 
        /// </summary>
        /// <param name="viewModel"></param>
        /// <returns></returns>
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Save(EntryViewModel viewModel)
        {
            //if (!SaveCustomer(viewModel.Customer))
            //    return RedirectToAction("Index", "Entry", new {@id= + viewModel.Id});

            var registration = PrepareDomainModel(viewModel);
            if (registration.Id == 0)
                _registrationService.InsertRegistration(registration);
            else
                _registrationService.UpdateRegistration(registration);
            
            return RedirectToAction("Index", "Entry", new {id = registration.Id});
            //return RedirectToAction("Index", "Entry", new {@id = registration.Id});

        }
        /// <summary>
        /// Delete selected assignment
        /// </summary>
        /// <param name="rId">registation id</param>
        /// /// <param name="aId">assignment id</param>
        /// <returns></returns>
        public ActionResult DelAssignment(int rId,int aId)
        {
            _assignmentService.DelAssignment(aId);
            return RedirectToAction("Index", "Entry", new { id = rId });
            
        }
        [AcceptVerbs(HttpVerbs.Get)]
        public JsonResult GetCustomers(string filter)
        {
            var where = PrepareFilter(filter);
            var customers = _customerService.GetCustomers(where);

            var jsonData = new
                               {
                                   rows = customers.Select(x =>
                                                               {
                                                                   var customerViewModel = new CustomerViewModel();
                                                                   var mapper = new CustomerViewModelMapper();
                                                                   mapper.MapDomainToView(x, customerViewModel);
                                                                   return customerViewModel;
                                                               }).ToList()
                               };

            var result = Json(jsonData, JsonRequestBehavior.AllowGet);
            return result;
        }

        #region Private methods
        private List<Registration> GetList()
        {
            return _registrationService.GetAllActiveRegistrations().ToList();
        }

        private EntryViewModel PrepareViewModel(Registration registration)
        {
            var entryViewModel = new EntryViewModel();

            var mapper = new EntryViewModelMapper(_employeeService, _nailServiceService, _customerService);
            mapper.MapDomainToView(registration, entryViewModel);

            List<Registration> domainModel = GetList();
            GenericListViewModel<RegistrationListViewItem> viewModel = new GenericListViewModel<RegistrationListViewItem>();

            var _listMapper = new RegistrationListViewModelMapper();

            _listMapper.MapDomainToView(domainModel, viewModel);
            entryViewModel.Registrations = viewModel;

            return entryViewModel;
        }

        private Registration PrepareDomainModel(EntryViewModel viewModel)
        {
            var registration = viewModel.RegistrationId == 0
                                   ? new Registration()
                                   : _registrationService.GetRegistration(viewModel.RegistrationId);

            var mapper = new EntryViewModelMapper(_employeeService, _nailServiceService, _customerService);
            mapper.MapViewToDomain(viewModel, registration);

            var user = User as User;
            if (user != null)
            {
                registration.NailSalon = user.NailSalon;
                registration.Customer.NailSalon = user.NailSalon;
            }

            registration.EndTime = DateTime.Now;
            return registration;
        }

        private Expression<Func<Customer, bool>> PrepareFilter(string queryString)
        {
            var filter = queryString.Split(new char[] {'='});
            Expression<Func<Customer, bool>> where;

            switch (filter[0].ToLower())
            {
                case "firstname":
                    where = x => x.FirstName == filter[1];
                    break;
                case "lastname":
                    where = x => x.LastName == filter[1];
                    break;
                default:
                    where = x => true;
                    break;
            }

            return where;
        }

        #endregion
        
        #region ajax method
        //[AcceptVerbs(HttpVerbs.Post)]
        ////[CultureAwareAction]
        //[GridAction]
        //public ActionResult _InsertAjaxEditing()
        //{
        //    //Create a new instance of the EditableProduct class.
        //    EditableProduct product = new EditableProduct();

        //    //Perform model binding (fill the product properties and validate it).
        //    if (TryUpdateModel(product))
        //    {
        //        //The model is valid - insert the product.
        //        SessionProductRepository.Insert(product);
        //    }

        //    //Rebind the grid
        //    return View(new GridModel(SessionProductRepository.All()));
        //}


        #endregion

        #region View Task
        [ActionName("InitializeTask")]
        [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post | HttpVerbs.Head)]

        public ActionResult InitializeTask()
        {
            return PartialView("_Task", _taskManager.GetTaskModel());
        }
        #endregion

    }
}
